home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Original Shareware 1.1
/
The Original Shareware (WeMake CDs)(Volume 1.1)(CDs, Inc)(1993).iso
/
18
/
fpc103.zip
/
MULTASK.SEQ
< prev
next >
Wrap
Text File
|
1988-06-30
|
6KB
|
157 lines
\ MULTASK.SEQ Multi tasking code for Forth.
PREFIX
ONLY FORTH ALSO DEFINITIONS
comment:
The MultiTasker is loaded as an application on top of the
regular Forth System. There is support for it in the nucleus
in the form of USER variables and PAUSEs inserted inside of
KEY EMIT and BLOCK. The Forth multitasking scheme is
co-operative instead of interruptive. All IO operations cause
a PAUSE to occur, and the multitasking loop looks around at
all of the current task for something to do.
Modified by Tom Zimmer to work with F-PC, which needs to save the ES
register along with IP. - 2/29/88 -
NOTICE !! This multi tasking DOES NOT SUPPORT MULTIPLE USERS !!!
There are a significant number of things what will have to be changed
in this Forth system to support multi user, like the editor would have
to be re-written, ect. So I am not supporting multi user, only
background processing.
Background processing MAY NOT do any compiling, compile, like VARIABLE,
or CREATE, ect. at *** RUNTIME ***. 06/06/88 13:58
YDP and XDP are NOT user variables.
comment;
CODE (PAUSE) ( -- )
PUSH ES \ Push ES, IP, and RP
PUSH IP
PUSH RP
MOV BX, UP \ make BX point to user area
MOV 0 [BX], SP \ save SP in user area offset 0
ADD BX, # 4 \ adjust BX to point to LINK
ADD BX, 0 [BX] \ Add value in LINK to BX, pointing it to
\ next tasks user area offset 0
ADD BX, # 2 \ bump BX 2 to point to ENTRY
JMP BX \ jump to next tasks entry point
END-CODE
CODE RESTART ( -- )
POP BX \ pop address of where we came from
MOV AX, # -4
ADD BX, AX \ adjust to beginning of user area
MOV UP BX \ set UP to point to begin of user area
POP AX \ pop off old PC
POPF \ restore status register
MOV SP, 0 [BX] \ restore SP (stack pointer)
POP RP \ restore RP, IP, and ES
POP IP
POP ES
NEXT END-CODE
HEX E9 CONSTANT INT#
: LOCAL ( base addr -- addr' ) UP @ - + ;
: @LINK ( -- addr ) LINK DUP @ + 2+ ;
: !LINK ( addr -- ) LINK 2+ - LINK ! ;
: SLEEP ( addr -- ) E990 SWAP ENTRY LOCAL ! ;
: WAKE ( addr -- ) E9CD SWAP ENTRY LOCAL ! ;
: STOP ( -- ) UP @ SLEEP PAUSE ;
: SINGLE ( -- )
E9 ['] PAUSE C! \ set JMP in PAUSE
>NEXT ['] PAUSE >BODY - \ get offset to NEXT
['] PAUSE 1+ ! ; \ store in PAUSE + 1
HEX
CODE MULTI ( -- )
MOV ' PAUSE # E9
MOV BX, # ' (PAUSE) ' PAUSE 3 + - \ relative I hope!
MOV ' PAUSE 1+ BX
MOV BX, # ' RESTART
MOV AX, DS
PUSH AX
SUB AX, AX MOV DS, AX
MOV AX, CS MOV INT# 4 * 2+ AX
MOV INT# 4 * BX
POP AX
MOV DS, AX NEXT
END-CODE
UP @ WAKE ENTRY !LINK
DECIMAL
: TASK: ( size -- )
CREATE TOS HERE #USER @ CMOVE ( Copy the USER Area )
@LINK UP @ -ROT HERE UP ! !LINK ( I point where he did)
DUP HERE + DUP RP0 ! 100 - SP0 ! SWAP UP !
HERE ENTRY LOCAL !LINK ( He points to me)
HERE #USER @ + HERE DP LOCAL !
HERE SLEEP ALLOT ;
: SET-TASK ( ES ip task -- ) \ NOTE: both ES and IP are passed
\ to SET-TASK.
>R SWAP R>
DUP SP0 LOCAL @ \ Top of Stack
2- ROT OVER ! \ Initial ES
2- ROT OVER ! \ Initial IP
2- OVER RP0 LOCAL @ OVER ! \ Initial RP
SWAP TOS LOCAL ! ;
: ACTIVATE ( task -- )
DUP
R> R> SWAP ROT SET-TASK WAKE ;
: BACKGROUND: ( -- )
400 TASK:
XHERE @LINK 2- \ get address of new task, note that
\ XHERE returns SEGMENT and OFFSET,
\ which is used by SET-TASK
SET-TASK !CSP ] ;
comment:
Here is a sample of how to create a background task that will do a
listing of the current file, with the hypothetical word FUNCTION1. The
task MYTASK is created with the default function FUNCTION1 assigned to it.
Next we define a word MYTASK-THIS, what changes the function assigned to
MYTASK to perform FUNCTION2. This allows us to change the function a
task performs without having to define a new task. In each case, the
task is stopped after its assigned FUNCTION is performed.
background: mytask function1 stop ;
: mytask-this mytask activate function2 stop ;
This next example defines a variable, and a routine which increments
the variable in the background. Notice that the program is an infinite
loop, and will only stop when put to sleep, or when multi tasking is
turned off with SINGLE. This example will actually work, you might try
typing it into a file and loading it.
variable counts
background: counter begin pause 1 counts +! again ;
MULTI COUNTER WAKE \ start up the COUNTER task
\ COUNTER SLEEP \ put the COUNTER task to sleep
\ SINGLE \ disable multi tasking
comment;
ONLY FORTH ALSO DEFINITIONS